package com.xz.purchase.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xz.apply.domain.PurchaseApply;
import com.xz.apply.domain.PurchaseProductApply;
import com.xz.apply.service.IPurchaseApplyService;
import com.xz.apply.service.IPurchaseProductApplyService;
import com.xz.common.annotation.DataScope;
import com.xz.common.core.domain.AjaxResult;
import com.xz.common.exception.ServiceException;
import com.xz.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.common.utils.RedisCode;
import com.xz.common.utils.SecurityUtils;
import com.xz.common.utils.StringUtils;
import com.xz.common.utils.uuid.IdUtils;
import com.xz.log.domain.OperationLog;
import com.xz.log.service.IOperationLogService;
import com.xz.process.domain.ProcessOrder;
import com.xz.process.domain.ProcessOrderItem;
import com.xz.process.service.IProcessOrderItemService;
import com.xz.process.service.IProcessOrderService;
import com.xz.product.domain.Product;
import com.xz.product.dto.ProductDto;
import com.xz.product.service.IProductService;
import com.xz.product.vo.ProductCategoryVo;
import com.xz.purchase.domain.PurchaseProductParam;
import com.xz.purchase.dto.PurchaseDto;
import com.xz.purchase.dto.PurchaseImportVo;
import com.xz.purchase.dto.PurchaseInfoDto;
import com.xz.purchase.domain.PurchasePrice;
import com.xz.purchase.domain.PurchaseProduct;
import com.xz.purchase.dto.PurchaseStatisticsDto;
import com.xz.purchase.service.IPurchasePriceService;
import com.xz.purchase.service.IPurchaseProductParamService;
import com.xz.purchase.service.IPurchaseProductService;
import com.xz.purchase.vo.*;
import com.xz.purchaseOrder.domain.PurchaseOrder;
import com.xz.purchaseOrder.domain.PurchaseProductOrder;
import com.xz.purchaseOrder.service.IPurchaseOrderService;
import com.xz.purchaseOrder.service.IPurchaseProductOrderService;
import com.xz.repertory.domain.RepertoryFlow;
import com.xz.repertory.service.IRepertoryFlowService;
import com.xz.sales.domain.SalesOrderDetail;
import com.xz.sales.domain.SalesPurchase;
import com.xz.sales.mapper.SalesOrderMapper;
import com.xz.sales.mapper.SalesPurchaseMapper;
import com.xz.sales.service.ISalesOrderDetailService;
import com.xz.sales.service.ISalesOrderService;
import com.xz.supplier.domain.Supplier;
import com.xz.supplier.service.ISupplierService;
import com.xz.warehouse.domain.Warehouse;
import com.xz.warehouse.service.IWarehouseService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xz.purchase.mapper.PurchaseMapper;
import com.xz.purchase.domain.Purchase;
import com.xz.purchase.service.IPurchaseService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 采购Service业务层处理
 *
 * @author xz
 * @date 2024-01-06
 */
@Service
public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, Purchase> implements IPurchaseService {
    @Autowired
    private PurchaseMapper purchaseMapper;
    @Autowired
    private IPurchaseProductService iPurchaseProductService;
    @Autowired
    private IRepertoryFlowService iRepertoryFlowService;
    @Autowired
    private IWarehouseService iWarehouseService;
    @Autowired
    private IPurchasePriceService iPurchasePriceService;
    @Autowired
    private IProductService iProductService;
    @Autowired
    private IPurchaseProductOrderService iPurchaseProductOrderService;
    @Autowired
    private IPurchaseOrderService iPurchaseOrderService;
    @Autowired
    private IPurchaseApplyService iPurchaseApplyService;
    @Autowired
    private IPurchaseProductApplyService iPurchaseProductApplyService;
    @Autowired
    private IProcessOrderItemService iProcessOrderItemService;
    @Autowired
    private IProcessOrderService iProcessOrderService;
    @Autowired
    private ISalesOrderDetailService iSalesOrderDetailService;
    @Autowired
    private ISupplierService iSupplierService;
    @Resource
    private SalesPurchaseMapper salesPurchaseMapper;
    @Autowired
    private IOperationLogService operationLogService;

    /**
     * 查询采购
     *
     * @param id 采购主键
     * @return 采购
     */
    @Override
    public PurchaseInfoDto selectPurchaseById(Long id) {
        PurchaseInfoDto purchaseInfoDto = purchaseMapper.selectPurchaseById(id);
        if(Objects.nonNull(purchaseInfoDto)){
            List<PurchaseProduct> purchaseProductList = purchaseInfoDto.getPurchaseProductList();
            for(PurchaseProduct purchaseProduct :purchaseProductList){
                List<PurchaseProductParam> purchaseProductParamList =new ArrayList<>();
                String productParam = purchaseProduct.getProductParam();
                if(Objects.nonNull(productParam)){
                    List<String> list = Arrays.asList(productParam.split(";"));
                    for(String params:list){
                        String[] split = params.trim().split(":");
                        if(split.length==2){
                            PurchaseProductParam purchaseProductParam=new PurchaseProductParam();
                            purchaseProductParam.setAttributeName(split[0].trim());
                            purchaseProductParam.setAttributeParameter(split[1].trim());
                            purchaseProductParamList.add(purchaseProductParam);
                        }
                    }
                }
                purchaseProduct.setPurchaseProductParamList(purchaseProductParamList);
            }
        }

        return purchaseInfoDto;
    }

    /**
     * 导入库存商品
     * @param list
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult importExcel(List<PurchaseImportVo> list) {
        if(CollectionUtils.isEmpty(list)){
            return AjaxResult.error("导入数量不能为空");
        }
        //商品数据
        Product product = new Product();
        product.setStatus("0");
        List<ProductDto> productList = iProductService.selectProductList(product);
        //仓库
        List<Warehouse> warehouseList = iWarehouseService.list(new QueryWrapper<Warehouse>().eq("status",0).eq("del_flag",0));
        //供应商
        List<Supplier> supplierList = iSupplierService.list(new QueryWrapper<Supplier>().eq("status",0).eq("del_flag",0));
        List<PurchaseProduct> purchaseProductList=new ArrayList<>();
        StringBuilder errorMsg=new StringBuilder();
        for(PurchaseImportVo importVo:list){

            List<ProductDto> productDtos = productList.stream().filter(i -> i.getProductName().equals(importVo.getProductName())).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(productDtos)){
                errorMsg.append("<br/>商品【" + importVo.getProductName() + "】不存在! ");
                continue;
            }

            List<Warehouse> warehouses = warehouseList.stream().filter(i -> i.getWarehouseName().equals(importVo.getWarehouseName())).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(warehouses)){
                errorMsg.append("<br/>仓库【" + importVo.getWarehouseName() + "】不存在! ");
                 continue;
            }
            List<Supplier> suppliers = supplierList.stream().filter(i -> i.getUnitName().equals(importVo.getSupplierName())).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(suppliers)){
                errorMsg.append("<br/>供应商【" + importVo.getSupplierName() + "】不存在! ");
                continue;
            }
            importDateProcessing(importVo,productDtos,warehouses,suppliers,purchaseProductList);
        }
        if(CollectionUtils.isEmpty(purchaseProductList)){
            return AjaxResult.error("导入失败"+(StringUtils.isEmpty(errorMsg)?"":","+errorMsg.toString()));
        }
        boolean savedBatch = iPurchaseProductService.saveBatch(purchaseProductList);
        if(!savedBatch){
            throw new ServiceException("导入失败");
        }
        //库存流水
        if(!CollectionUtils.isEmpty(purchaseProductList)){
            iRepertoryFlowService.saveRepertoryFlowList(purchaseProductList,1,1);
        }
        return AjaxResult.success("导入成功"+(StringUtils.isEmpty(errorMsg)?"":",部分数导入失败<br/>"+errorMsg.toString()));
    }

    public void importDateProcessing(PurchaseImportVo importVo,List<ProductDto> productDtos,List<Warehouse> warehouses,List<Supplier> suppliers,List<PurchaseProduct> purchaseProductList){
        Purchase purchase=new Purchase();
        PurchaseProduct purchaseProduct=new PurchaseProduct();
        ProductDto productDto = productDtos.get(0);
        Warehouse warehouse = warehouses.get(0);
        Supplier supplier = suppliers.get(0);
        purchase.setSupplierName(supplier.getUnitName());
        purchase.setSupplierId(supplier.getId());
        purchase.setWarehouseName(warehouse.getWarehouseName());
        purchase.setWarehouseId(warehouse.getId());
        purchase.setStatus(2);
        purchase.setDeptId(warehouse.getDeptId());
        purchase.setPurchaseNumber(RedisCode.getCode("RK"));
        purchase.setCreateTime(DateUtils.getNowDate());
        purchase.setCreateBy(SecurityUtils.getUserId());
        purchase.setTenantId(SecurityUtils.getLoginUser().getTenantId());
        purchase.setStorageType(1);
        int insertPurchase = purchaseMapper.insertPurchase(purchase);
        purchaseProduct.setPurchaseId(purchase.getId());
        purchaseProduct.setStorageNum(importVo.getStorageNum());
        purchaseProduct.setBatchDate(importVo.getBatchDate());
        purchaseProduct.setBatchNumber(importVo.getBatchNumber());
        purchaseProduct.setValidity(importVo.getValidity());
        purchaseProduct.setManufacturer(productDto.getManufacturer());
        purchaseProduct.setRegistrationNumber(productDto.getRegistrationNo());
        purchaseProduct.setProductName(productDto.getProductName());
        purchaseProduct.setProductId(productDto.getId());
        purchaseProduct.setProductEncoded(productDto.getEncoded());
        purchaseProduct.setStatus(1);
        purchaseProduct.setSupplierId(purchase.getSupplierId());
        purchaseProduct.setSupplierName(purchase.getSupplierName());
        purchaseProduct.setWarehouseId(purchase.getWarehouseId());
        purchaseProduct.setWarehouseName(purchase.getWarehouseName());
        purchaseProduct.setCostPrice(importVo.getCostPrice());
        purchaseProduct.setUnit(importVo.getUnit());
        purchaseProduct.setCreateBy(purchase.getCreateBy());
        purchaseProduct.setCreateTime(purchase.getCreateTime());
        purchaseProduct.setTenantId(purchase.getTenantId());
        purchaseProduct.setDeptId(purchase.getDeptId());
        purchaseProduct.setBrandName(productDto.getBrandName());
        purchaseProduct.setProdName(productDto.getProdName());
        purchaseProduct.setProductCategory(productDto.getProductCategory());
        purchaseProduct.setAvailableStock(importVo.getStorageNum());
        purchaseProduct.setStorageNum(importVo.getStorageNum());
        purchaseProduct.setPurchaseNumber(purchase.getPurchaseNumber());
        purchaseProduct.setInventoryQuantity(importVo.getStorageNum());
        StringBuilder builder=new StringBuilder();
        if(StringUtils.isNotEmpty(importVo.getParameterOne())){
            builder.append("球镜："+importVo.getParameterOne()+"；");
        }
        if(StringUtils.isNotEmpty(importVo.getParameterTwo())){
            builder.append("柱镜："+importVo.getParameterTwo()+"；");
        }
        if(StringUtils.isNotEmpty(importVo.getParameterThree())){
            builder.append("轴向："+importVo.getParameterThree()+"；");
        }
        if(StringUtils.isNotEmpty(importVo.getParameterFour())){
            builder.append("尺寸："+importVo.getParameterFour()+"；");
        }
        if(StringUtils.isNotEmpty(importVo.getParameterFive())){
            builder.append("颜色："+importVo.getParameterFive()+"；");
        }
        if(StringUtils.isNotEmpty(importVo.getParameterSix())){
            builder.append("其他参数："+importVo.getParameterSix()+"；");
        }
        purchaseProduct.setProductParam(builder.toString());
        purchaseProductList.add(purchaseProduct);
    }

    /**
     * 查询采购列表
     *
     * @param purchase 采购
     * @return 采购
     */
    @DataScope(deptAlias = "d", userAlias = "u")
    @Override
    public List<PurchaseDto> selectPurchaseList(Purchase purchase) {
        return purchaseMapper.selectPurchaseList(purchase);
    }

    /**
     * 新增采购
     *
     * @param purchase 采购
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertPurchase(Purchase purchase) {
        List<PurchaseProduct> purchaseProductList = purchase.getPurchaseProductList();
        if(CollectionUtils.isEmpty(purchaseProductList)){
            return AjaxResult.error("商品不能为空");
        }
        //仓库所属部门
        Warehouse warehouse = iWarehouseService.getById(purchase.getWarehouseId());
        if(Objects.isNull(warehouse)){
            return AjaxResult.error("仓库不存在");
        }
        if(Objects.isNull(purchase.getDeptId())){
            purchase.setDeptId(warehouse.getDeptId());
        }
        if(StringUtils.isEmpty(purchase.getPurchaseNumber())){
            purchase.setPurchaseNumber(RedisCode.getCode("RK"));
        }
        purchase.setCreateTime(DateUtils.getNowDate());
        purchase.setCreateBy(SecurityUtils.getUserId());
        purchase.setTenantId(SecurityUtils.getLoginUser().getTenantId());
        int insertPurchase = purchaseMapper.insertPurchase(purchase);
        if(insertPurchase>0){
            if(purchase.getStorageType()==2){
                purchase.setStorageType(1);
            }
            dataPurchaseProduct(purchaseProductList,purchase);
        }
        return insertPurchase>0? AjaxResult.success("新增成功",purchase.getId()):AjaxResult.error("新增失败");
    }

    /**
     * 修改采购
     *
     * @param purchase 采购
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updatePurchase(Purchase purchase) {
        if(purchase.getId()==null){
            return AjaxResult.error("参数id不能为空");
        }
        List<PurchaseProduct> purchaseProductList = purchase.getPurchaseProductList();
        if(CollectionUtils.isEmpty(purchaseProductList)){
            return AjaxResult.error("商品不能为空");
        }
        //仓库所属部门
        Warehouse warehouse = iWarehouseService.getById(purchase.getWarehouseId());
        if(Objects.isNull(warehouse)){
            return AjaxResult.error("仓库不存在");
        }
        purchase.setDeptId(warehouse.getDeptId());
        purchase.setUpdateTime(DateUtils.getNowDate());
        purchase.setUpdateBy(SecurityUtils.getUserId());
        int updatePurchase = purchaseMapper.updatePurchase(purchase);
        if(updatePurchase>0){
            //删除库存商品重新录入
            iPurchaseProductService.deletePurchaseProductById(purchase.getId());
            if(purchase.getStorageType()==2){
                purchase.setStorageType(1);
            }
            dataPurchaseProduct(purchaseProductList,purchase);
        }
        return updatePurchase>0? AjaxResult.success("修改成功"):AjaxResult.error("修改失败");
    }

    /**
     * 数据处理
     * @param purchaseProductList
     * @param purchase
     */
    public void dataPurchaseProduct(List<PurchaseProduct> purchaseProductList,Purchase purchase){
        purchaseProductList.stream().forEach(i->{
            if(Objects.nonNull(purchase.getStorageType()) && purchase.getStorageType().equals(13)){
                // 嫌麻烦 所以上面这么判断
                i.setCostPrice(i.getCostPrice());
            }else {
                BigDecimal price = iPurchasePriceService.insertPurchasePrice(new PurchasePrice(purchase.getSupplierId(), i.getProductId(), purchase.getTenantId()));
                i.setCostPrice(price);
            }
            i.setCreateBy(purchase.getCreateBy());
            i.setWarehouseId(purchase.getWarehouseId());
            i.setSupplierId(purchase.getSupplierId());
            i.setPurchaseId(purchase.getId());
            i.setAvailableStock(i.getStorageNum());
            i.setWarehouseName(purchase.getWarehouseName());
            i.setSupplierName(purchase.getSupplierName());
            if(StringUtils.isEmpty(i.getBatchNumber())){
                i.setBatchNumber("-");
            }
            StringBuilder stringBuilder=new StringBuilder();
            if(purchase.getStorageType()==1 && StringUtils.isEmpty(i.getProductParam())){
                i.getPurchaseProductParamList().forEach(j->{
                    stringBuilder.append(j.getAttributeName()+"："+j.getAttributeParameter()+"；");
                });
                i.setProductParam(stringBuilder.toString());
            }
            i.setStatus(1);
            i.setDeptId(purchase.getDeptId());
            i.setTenantId(purchase.getTenantId());
            i.setPurchaseNumber(purchase.getPurchaseNumber());
            i.setInventoryQuantity(i.getAvailableStock());
            i.setCreateBy(purchase.getUpdateBy()!=null?purchase.getUpdateBy():purchase.getCreateBy());
            i.setBusinessId(purchase.getId());
            i.setCreateTime(DateUtils.getNowDate());
            ProductCategoryVo productCategory = iProductService.getProductCategory(i.getProductId());
            if(Objects.nonNull(productCategory)){
                i.setBrandName(productCategory.getBrandName());
                i.setProdName(productCategory.getProdName());
                i.setProductCategory(productCategory.getProductCategory());
                if(Objects.isNull(i.getManufacturer())){
                    i.setManufacturer(productCategory.getManufacturer());
                }
                if(Objects.isNull(i.getRegistrationNumber())){
                    i.setRegistrationNumber(productCategory.getRegistrationNo());
                }
                if(Objects.isNull(i.getProductEncoded())){
                    i.setProductEncoded(productCategory.getEncoded());
                }
                if(Objects.isNull(i.getUnit())){
                    i.setUnit(productCategory.getUnit());
                }
            }
        });
        boolean saveBatch = iPurchaseProductService.saveBatch(purchaseProductList);
        if(!saveBatch){
            throw new ServiceException("新增失败");
        }
        //库存流水
        if(purchase.getStatus()==2&&!CollectionUtils.isEmpty(purchaseProductList)){
            if(purchase.getStorageType() != 1){
                iRepertoryFlowService.saveRepertoryFlowList(purchaseProductList,1,purchase.getStorageType());
            }else {
                iRepertoryFlowService.saveRepertoryFlowList(purchaseProductList,1,1);
            }
        }
    }
    /**
     * 批量删除采购
     *
     * @param ids 需要删除的采购主键
     * @return 结果
     */
    @Override
    public int deletePurchaseByIds(Long[] ids) {
        return purchaseMapper.deletePurchaseByIds(ids);
    }

    /**
     * 删除采购信息
     *
     * @param id 采购主键
     * @return 结果
     */
    @Override
    public int deletePurchaseById(Long id) {
        return purchaseMapper.deletePurchaseById(id);
    }

    /**
     * 冲红
     * @param blushVo
     * @return
     */
    @Override
    public AjaxResult blush(BlushVo blushVo) {
        if(blushVo.getType()==1){
            if(CollectionUtils.isEmpty(blushVo.getIdList())){
                return AjaxResult.error("请选择冲红商品");
            }
        }
        if(blushVo.getType()==2){
            List<PurchaseProduct> list = iPurchaseProductService.list(new QueryWrapper<PurchaseProduct>().eq("purchase_id", blushVo.getId()).eq("status", 1));
            if(!CollectionUtils.isEmpty(list)){
                List<Long> collected = list.stream().map(i -> i.getId()).collect(Collectors.toList());
                blushVo.setIdList(collected);
            }
        }
        if(CollectionUtils.isEmpty(blushVo.getIdList())){
            return AjaxResult.success("暂无可冲红商品");
        }
        int blush = iPurchaseProductService.blush(blushVo.getIdList());
        if(blush>0){
            int count = iPurchaseProductService.count(new QueryWrapper<PurchaseProduct>().eq("purchase_id", blushVo.getId()).eq("status", 1));
            Purchase purchase = baseMapper.selectById(blushVo.getId());
            if(Objects.isNull(purchase)){
                return AjaxResult.error("冲红失败");
            }
            purchase.setStatus(count>0?4:3);
            purchase.setUpdateTime(DateUtils.getNowDate());
            purchase.setUpdateBy(SecurityUtils.getUserId());
            int updatePurchase = purchaseMapper.updatePurchase(purchase);
            if(updatePurchase>0){
                List<PurchaseProduct> list =new ArrayList<>();
                blushVo.getIdList().stream().forEach(i->{
                    PurchaseProduct purchaseProductInfo = iPurchaseProductService.getPurchaseProductInfo(i);
                    if(!Objects.isNull(purchaseProductInfo)){
                        purchaseProductInfo.setCreateBy(SecurityUtils.getUserId());
                        purchaseProductInfo.setCreateTime(new Date());
                        purchaseProductInfo.setInventoryQuantity(purchaseProductInfo.getAvailableStock());
                        list.add(purchaseProductInfo);
                    }
                });
                if(!CollectionUtils.isEmpty(list)){
                    boolean flow = false;
                    if(purchase.getStorageType().equals(1) || purchase.getStorageType().equals(2)){
                        flow = iRepertoryFlowService.saveRepertoryFlow(list, 1, 2);
                    }else {
                        flow = iRepertoryFlowService.saveRepertoryFlow(list, 1, 11);
                    }
                    if(flow){
                        return AjaxResult.success("冲红成功");
                    }
                }
            }
        }
        return AjaxResult.error("冲红失败");
    }

    /**
     * 商品维度统计
     * @param purchaseProduct
     * @return
     */
    @Override
    public List<CommodityDimensionStatisticsVo> commodityDimensionStatisticsList(PurchaseProduct purchaseProduct) {
        //商品维度统计
        List<CommodityDimensionStatisticsVo> statisticsVoList = baseMapper.commodityDimensionStatistics(purchaseProduct);
        //调拨在途
        List<TransferStockVo> stockVoList = baseMapper.transferStock(purchaseProduct);
        //采购在途
        List<PurchaseTransitVo> transitVoList = baseMapper.purchaseTransit(purchaseProduct);
        //预占库存
        List<SalesStockVo> salesStockVoList = baseMapper.salesStock(purchaseProduct);

        for (CommodityDimensionStatisticsVo statisticsVo:statisticsVoList){
            statisticsVo.setPurchaseInventory(0);
            //采购在途
            Integer transitStock=transitStock(transitVoList,statisticsVo.getProductName(),statisticsVo.getProductParam(),statisticsVo.getWarehouseId(),purchaseProduct,"");
            statisticsVo.setPurchaseInventory(transitStock);
            Integer availableStockTotal = statisticsVo.getAvailableStockTotal();//总库存

            //调拨在途
            Integer transferStock=transferStock(stockVoList,statisticsVo.getProductName(),statisticsVo.getProductParam(),statisticsVo.getWarehouseId(),purchaseProduct,"");
            statisticsVo.setTransferStock(transferStock);
            //销售在途
            Integer salesStock=salesStock(salesStockVoList,statisticsVo.getProductName(),statisticsVo.getProductParam(),statisticsVo.getWarehouseId(),purchaseProduct,"");
            statisticsVo.setPreoccupiedInventory(salesStock);
            statisticsVo.setTransferStock(transferStock);
            statisticsVo.setAvailableStock(availableStockTotal);
            statisticsVo.setAvailableStockTotal(statisticsVo.getAvailableStockTotal()+salesStock+transferStock);
        }

        return statisticsVoList;
    }

    /**
     * 即使库存--财务纬度
     * @param purchaseProduct
     * @return
     */
    public List<BillDimensionStatisticsVo> billDimensionStatisticsList(PurchaseProduct purchaseProduct) {
        //商品维度统计
        List<BillDimensionStatisticsVo> statisticsVoList = baseMapper.billDimensionStatistics(purchaseProduct);
        //调拨在途
        List<TransferStockVo> stockVoList = baseMapper.transferStock(purchaseProduct);
        //采购在途
        List<PurchaseTransitVo> transitVoList = baseMapper.purchaseTransit(purchaseProduct);
        //预占库存
        List<SalesStockVo> salesStockVoList = baseMapper.salesStock(purchaseProduct);
        for (BillDimensionStatisticsVo statisticsVo:statisticsVoList){
            statisticsVo.setPurchaseInventory(0);
            //采购在途
            Integer transitStock=transitStock(transitVoList,statisticsVo.getProductName(),statisticsVo.getProductParam(),statisticsVo.getWarehouseId(),purchaseProduct,"");
            statisticsVo.setPurchaseInventory(transitStock);
            Integer availableStockTotal = statisticsVo.getAvailableStockTotal();//总库存
            //调拨在途
            Integer transferStock=transferStock(stockVoList,statisticsVo.getProductName(),statisticsVo.getProductParam(),statisticsVo.getWarehouseId(),purchaseProduct,"");
            statisticsVo.setTransferStock(transferStock);
            //销售在途
            Integer salesStock=salesStock(salesStockVoList,statisticsVo.getProductName(),statisticsVo.getProductParam(),statisticsVo.getWarehouseId(),purchaseProduct,"");
            statisticsVo.setPreoccupiedInventory(salesStock);
            statisticsVo.setAvailableStock(availableStockTotal);
            statisticsVo.setAvailableStockTotal(statisticsVo.getAvailableStockTotal()+salesStock+transferStock);
            statisticsVo.setAmountTotal(statisticsVo.getCostPrice().multiply(BigDecimal.valueOf(statisticsVo.getAvailableStockTotal())));
        }

        return statisticsVoList;
    }
    //调拨在途
    public Integer transferStock(List<TransferStockVo> stockVoList,String productName,String productParam,Long warehouseId,PurchaseProduct purchaseProduct,String batchNumber){
        //调拨在途
        List<TransferStockVo> collect=null;
        if(StringUtils.isNotEmpty(batchNumber)) {//批次号筛选
            if (purchaseProduct.getWarehouseId() != null) {//仓库筛选
                if (StringUtils.isNotEmpty(productParam)) {
                    collect = stockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                                    && warehouseId.equals(i.getWarehouseId())
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                } else {
                    collect = stockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && warehouseId.equals(i.getWarehouseId())
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }
            } else {
                if (StringUtils.isNotEmpty(productParam)) {
                    collect = stockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                } else {
                    collect = stockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }
            }
        }else{
            if (purchaseProduct.getWarehouseId() != null) {//仓库筛选
                if (StringUtils.isNotEmpty(productParam)) {
                    collect = stockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                                    && warehouseId.equals(i.getWarehouseId())
                    ).collect(Collectors.toList());
                } else {
                    collect = stockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && warehouseId.equals(i.getWarehouseId())
                    ).collect(Collectors.toList());
                }
            } else {
                if (StringUtils.isNotEmpty(productParam)) {
                    collect = stockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                    ).collect(Collectors.toList());
                } else {
                    collect = stockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                    ).collect(Collectors.toList());
                }
            }
        }
        if(CollectionUtils.isEmpty(collect)){
            return 0;
        }
        TransferStockVo transferStockVo = collect.get(0);
        return transferStockVo.getTransferStock();
    }
    //销售在途
    public Integer salesStock(List<SalesStockVo> salesStockVoList,String productName,String productParam,Long warehouseId,PurchaseProduct purchaseProduct,String batchNumber){
        List<SalesStockVo> collect=null;
        if(StringUtils.isNotEmpty(batchNumber)) {//批次号筛选
            if(purchaseProduct.getWarehouseId()!=null){//仓库筛选
                if(StringUtils.isNotEmpty(productParam)){
                    collect = salesStockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                                    && warehouseId.equals(i.getWarehouseId())
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }else{
                    collect = salesStockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && warehouseId.equals(i.getWarehouseId())
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }
            }else{
                if(StringUtils.isNotEmpty(productParam)){
                    collect = salesStockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }else{
                    collect = salesStockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }
            }
        }else{
            if (purchaseProduct.getWarehouseId() != null) {//仓库筛选
                if (StringUtils.isNotEmpty(productParam)) {
                    collect = salesStockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                                    && warehouseId.equals(i.getWarehouseId())
                    ).collect(Collectors.toList());
                } else {
                    collect = salesStockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && warehouseId.equals(i.getWarehouseId())
                    ).collect(Collectors.toList());
                }
            } else {
                if (StringUtils.isNotEmpty(productParam)) {
                    collect = salesStockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                    ).collect(Collectors.toList());
                } else {
                    collect = salesStockVoList.stream().filter(i ->
                            i.getProductName().equals(productName)
                    ).collect(Collectors.toList());
                }
            }
        }
        if(CollectionUtils.isEmpty(collect)){
            return 0;
        }
        SalesStockVo salesStockVo = collect.get(0);
        return salesStockVo.getSalesStock();
    }
    //采购在途
    public Integer transitStock(List<PurchaseTransitVo> voList,String productName,String productParam,Long warehouseId,PurchaseProduct purchaseProduct,String batchNumber){
        List<PurchaseTransitVo> collect=null;
        if(StringUtils.isNotEmpty(batchNumber)){//批次号筛选
            if(purchaseProduct.getWarehouseId()!=null){//仓库筛选
                if(StringUtils.isNotEmpty(productParam)){
                    collect = voList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                                    && warehouseId.equals(i.getWarehouseId())
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }else{
                    collect = voList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && warehouseId.equals(i.getWarehouseId())
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }
            }else{
                if(StringUtils.isNotEmpty(productParam)){
                    collect = voList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }else{
                    collect = voList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && batchNumber.equals(i.getBatchNumber())
                    ).collect(Collectors.toList());
                }
            }
        }else{
            if(purchaseProduct.getWarehouseId()!=null){//仓库筛选
                if(StringUtils.isNotEmpty(productParam)){
                    collect = voList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                                    && warehouseId.equals(i.getWarehouseId())
                    ).collect(Collectors.toList());
                }else{
                    collect = voList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && warehouseId.equals(i.getWarehouseId())
                    ).collect(Collectors.toList());
                }
            }else{
                if(StringUtils.isNotEmpty(productParam)){
                    collect = voList.stream().filter(i ->
                            i.getProductName().equals(productName)
                                    && productParam.equals(i.getProductParam())
                    ).collect(Collectors.toList());
                }else{
                    collect = voList.stream().filter(i ->
                            i.getProductName().equals(productName)
                    ).collect(Collectors.toList());
                }
            }
        }
        if(CollectionUtils.isEmpty(collect)){
            return 0;
        }
        PurchaseTransitVo purchaseTransitVo = collect.get(0);
        return purchaseTransitVo.getPurchaseTransit();
    }

    /**
     * 批次维度统计
     * @param purchaseProduct
     * @return
     */
    @Override
    public List<BatchDimensionStatisticsVo> batchDimensionStatistics(PurchaseProduct purchaseProduct) {
        //商品维度统计
        List<BatchDimensionStatisticsVo> dimensionStatisticsVoList = baseMapper.batchDimensionStatistics(purchaseProduct);
        List<TransferStockVo> stockVoList = baseMapper.transferBatchStock(purchaseProduct);
        //采购在途
        List<PurchaseTransitVo> transitVoList = baseMapper.purchaseTransit(purchaseProduct);
        //预占库存
        List<SalesStockVo> salesStockVoList = baseMapper.salesBatchStock(purchaseProduct);
        for (BatchDimensionStatisticsVo statisticsVo:dimensionStatisticsVoList){
            //调拨在途
            List<TransferStockVo> stockVos = stockVoList.stream().filter(i ->
                    i.getProductName().equals(statisticsVo.getProductName())
                            && statisticsVo.getProductParam().equals(i.getProductParam())
                            && statisticsVo.getWarehouseId().equals(i.getWarehouseId())
                            && statisticsVo.getBatchNumber().equals(i.getBatchNumber())
            ).collect(Collectors.toList());
            statisticsVo.setTransferStock(0);
            if(!CollectionUtils.isEmpty(stockVos)){
                statisticsVo.setTransferStock(stockVos.get(0).getTransferStock());
            }
            Integer availableStockTotal = statisticsVo.getAvailableStockTotal();//总库存
            //采购在途
            List<PurchaseTransitVo> voList = transitVoList.stream().filter(i ->
                    i.getProductName().equals(statisticsVo.getProductName())
                            && statisticsVo.getProductParam().equals(i.getProductParam())
                            && statisticsVo.getWarehouseId().equals(i.getWarehouseId())
                            && statisticsVo.getBatchNumber().equals(i.getBatchNumber())
            ).collect(Collectors.toList());

            statisticsVo.setPurchaseInventory(0);
            if(!CollectionUtils.isEmpty(voList)){
                statisticsVo.setPurchaseInventory(voList.get(0).getPurchaseTransit());
            }

            //purchaseProduct.setWarehouseId(statisticsVo.getWarehouseId());
            //销售在途
            List<SalesStockVo> salesStockVos = salesStockVoList.stream().filter(i ->
                    i.getProductName().equals(statisticsVo.getProductName())
                            && statisticsVo.getProductParam().equals(i.getProductParam())
                            && statisticsVo.getWarehouseId().equals(i.getWarehouseId())
                            && statisticsVo.getBatchNumber().equals(i.getBatchNumber())
            ).collect(Collectors.toList());
            statisticsVo.setPreoccupiedInventory(0);
            if(!CollectionUtils.isEmpty(salesStockVos)){
                statisticsVo.setPreoccupiedInventory(salesStockVos.get(0).getSalesStock());
            }
            statisticsVo.setAvailableStock(availableStockTotal);
            statisticsVo.setAvailableStockTotal(statisticsVo.getAvailableStockTotal()+statisticsVo.getPreoccupiedInventory()+statisticsVo.getTransferStock());
        }

        return dimensionStatisticsVoList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult purchaseWarehousing(Purchase purchase) {
        List<PurchaseProduct> purchaseProductList = purchase.getPurchaseProductList();
        purchase.setStorageType(2);
        AjaxResult ajaxResult = insertPurchase(purchase);
        String string = String.valueOf(ajaxResult.get("code"));
        if("200".equals(string)){
            for(PurchaseProduct purchaseProduct:purchaseProductList){
                PurchaseProductOrder productOrder = iPurchaseProductOrderService.selectPurchaseProductOrderById(purchaseProduct.getPurchaseProductOrderId());
                // 定制采购、销售单采购申请 入库了之后 就得预占
                PurchaseOrder purchaseOrder = iPurchaseOrderService.getById(productOrder.getPurchaseOrderId());
                PurchaseProductApply productApplyInfo = iPurchaseProductApplyService.getById(productOrder.getPurchaseDetailId());
                if(Objects.nonNull(productApplyInfo)){
                    PurchaseApply purchaseApplyInfo = iPurchaseApplyService.getById(productApplyInfo.getPurchaseId());
                    if(Objects.nonNull(purchaseApplyInfo)){
                        if(purchaseOrder.getPurchaseType()==2 && purchaseApplyInfo.getProductApplyType()==3){
                            SalesOrderDetail salesOrderDetailInfo = iSalesOrderDetailService.selectSalesOrderDetailById(productApplyInfo.getBizDetailId());
                            // 销售单 需要预占库存 预占
                            purchaseProduct.setInventoryQuantity(purchaseProduct.getAvailableStock());
                            purchaseProduct.setAvailableStock(0);
                            iPurchaseProductService.updateById(purchaseProduct);
                            SalesPurchase salesPurchase = new SalesPurchase();
                            salesPurchase.setSalesId(salesOrderDetailInfo.getSalesId());
                            salesPurchase.setDetailId(productApplyInfo.getBizDetailId());
                            salesPurchase.setPurchaseProductId(purchaseProduct.getId());
                            salesPurchase.setPurchaseProductNum(purchaseProduct.getInventoryQuantity());
                            salesPurchaseMapper.insert(salesPurchase);
                            operationLogService.insertOperationLog(
                                    new OperationLog(salesPurchase.getId()+"",
                                            4,purchaseApplyInfo.getTenantId(),SecurityUtils.getUserId(),SecurityUtils.getUsername(),
                                            "销售明细id:"+salesOrderDetailInfo.getId()+",预占库存采购产品记录ID："+purchaseProduct.getId()+",预占数量："+purchaseProduct.getInventoryQuantity()));
                        }
                    }
                }


                if(Objects.isNull(productOrder)){
                    continue;
                }
                if(productOrder.getWaitPurchaseNum()>=purchaseProduct.getStorageNum()){
                    productOrder.setWaitPurchaseNum(productOrder.getWaitPurchaseNum()-purchaseProduct.getStorageNum());
                }else{
                    productOrder.setWaitPurchaseNum(0);
                }
                iPurchaseProductOrderService.updateById(productOrder);
                int count = iPurchaseProductOrderService.count(new QueryWrapper<PurchaseProductOrder>().eq("id", productOrder.getId()).gt("wait_purchase_num", 0));
                if(count==0){
                    int countTotal = iPurchaseProductOrderService.count(new QueryWrapper<PurchaseProductOrder>().eq("purchase_order_id", productOrder.getPurchaseOrderId()).gt("wait_purchase_num", 0));
                    if(countTotal==0){
                        purchaseOrder.setStatus(5);
                        iPurchaseOrderService.updateById(purchaseOrder);
                    }
                    //定制采购 更新状态
                    if(purchaseOrder.getPurchaseType()==2&&productOrder.getPurchaseDetailId()!=null){
                        PurchaseProductApply productApply = iPurchaseProductApplyService.getById(productOrder.getPurchaseDetailId());
                        if(Objects.nonNull(productApply)){
                            PurchaseApply purchaseApply = iPurchaseApplyService.getById(productApply.getPurchaseId());
                            if(purchaseApply.getProductApplyType()==2){//加工单
                                iProcessOrderItemService.updateProcessOrderItemById(purchaseApply.getBizId(),6);
                            }else if(purchaseApply.getProductApplyType()==3){//销售单

                                Integer nextStatus = iSalesOrderDetailService.getNextStatus(productApply.getBizDetailId(),1);
                                SalesOrderDetail salesOrderDetail =new SalesOrderDetail();
                                salesOrderDetail.setId(productApply.getBizDetailId());
                                salesOrderDetail.setProductStatus(nextStatus);
                                salesOrderDetail.setWarehouseId(purchaseProduct.getWarehouseId());
                                salesOrderDetail.setWarehouseName(purchaseProduct.getWarehouseName());
                                iSalesOrderDetailService.updateSalesOrderDetail(salesOrderDetail);
                                int salesOrderDetailIdCount = iProcessOrderItemService.count(new QueryWrapper<ProcessOrderItem>().eq("sales_order_detail_id", productApply.getBizDetailId()));
                                if(salesOrderDetailIdCount>0){
                                    iProcessOrderItemService.updateProcessOrderItemByDetailId(productApply.getBizDetailId(),3);
                                }
                                //判断销售商品是否要加工
                                SalesOrderDetail detailServiceById = iSalesOrderDetailService.getById(productApply.getBizDetailId());
                                if(Objects.nonNull(detailServiceById)){
                                    if(detailServiceById.getMachiningType()==1){
                                        int orderItemByDetailId = iProcessOrderItemService.updateProcessOrderItemByDetailId(productApply.getBizDetailId(), 3);
                                        ProcessOrderItem processOrderItem = iProcessOrderItemService.selectProcessInfo(productApply.getBizDetailId());
                                        if(Objects.nonNull(processOrderItem)){
                                            int counted = iProcessOrderItemService.count(new QueryWrapper<ProcessOrderItem>().in("status", 1,2).eq("process_order_id", processOrderItem.getProcessOrderId()));
                                            if(counted==0){
                                                ProcessOrder processOrderServiceById = iProcessOrderService.getById(processOrderItem.getProcessOrderId());
                                                if(Objects.nonNull(processOrderServiceById)){
                                                    processOrderServiceById.setProcessingStatus(2);
                                                    iProcessOrderService.updateById(processOrderServiceById);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return ajaxResult;
    }

    /**
     * 进销存统计
     * @param purchase
     * @return
     */
    @Override
    public List<PurchaseStatisticsVo> purchaseStatistics(Purchase purchase) {
        /*进销存期末统计*/
        List<PurchaseStatisticsVo> statisticsVoList = baseMapper.purchaseEndStatistics(purchase);
        if(!CollectionUtils.isEmpty(statisticsVoList)){
            PurchaseStatisticsDto purchaseStatisticsDto=new PurchaseStatisticsDto();
            BeanUtils.copyProperties(purchase,purchaseStatisticsDto);
            /*进销存期初统计*/
            List<PurchaseStatisticsVo> purchaseStatisticsVoList = baseMapper.purchaseBeginStatistics(purchaseStatisticsDto);
            /*进销存库存流水*/
            List<PurchaseFlowStatisticsVo> voList = baseMapper.purchaseFlowStatistics(purchaseStatisticsDto);


            for (PurchaseStatisticsVo purchaseStatisticsVo:statisticsVoList){
                List<PurchaseStatisticsVo> list = purchaseStatisticsVoList.stream().filter(item ->
                        item.getProductCategory().equals(purchaseStatisticsVo.getProductCategory())
                                && item.getWarehouseName().equals(purchaseStatisticsVo.getWarehouseName())
                                && item.getProductParam().equals(purchaseStatisticsVo.getProductParam())
                                && item.getProductName().equals(purchaseStatisticsVo.getProductName())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(list)){
                    purchaseStatisticsVo.setBeginAmount(BigDecimal.ZERO);
                    purchaseStatisticsVo.setBeginNum(0);
                }else{
                    PurchaseStatisticsVo statisticsVo = list.get(0);
                    purchaseStatisticsVo.setBeginAmount(statisticsVo.getBeginAmount());
                    purchaseStatisticsVo.setBeginNum(statisticsVo.getBeginNum());
                }
                //入库
                List<PurchaseFlowStatisticsVo> toList = voList.stream().filter(item -> item.getFlowType() == 1 &&
                        item.getProductCategory().equals(purchaseStatisticsVo.getProductCategory())
                        && item.getWarehouseName().equals(purchaseStatisticsVo.getWarehouseName())
                        && item.getProductParam().equals(purchaseStatisticsVo.getProductParam())
                        && item.getProductName().equals(purchaseStatisticsVo.getProductName())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(toList)){
                    purchaseStatisticsVo.setToAmount(BigDecimal.ZERO);
                    purchaseStatisticsVo.setToNum(0);
                }else{
                    PurchaseFlowStatisticsVo toVo = toList.get(0);
                    purchaseStatisticsVo.setToAmount(toVo.getCostAmount());
                    purchaseStatisticsVo.setToNum(toVo.getQuantity());
                }
                //出库
                List<PurchaseFlowStatisticsVo> outList = voList.stream().filter(item -> item.getFlowType() == 2 &&
                        item.getProductCategory().equals(purchaseStatisticsVo.getProductCategory())
                        && item.getWarehouseName().equals(purchaseStatisticsVo.getWarehouseName())
                        && item.getProductParam().equals(purchaseStatisticsVo.getProductParam())
                        && item.getProductName().equals(purchaseStatisticsVo.getProductName())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(outList)){
                    purchaseStatisticsVo.setOutAmount(BigDecimal.ZERO);
                    purchaseStatisticsVo.setOutNum(0);
                    continue;
                }
                PurchaseFlowStatisticsVo outVo = outList.get(0);
                purchaseStatisticsVo.setOutAmount(outVo.getCostAmount());
                purchaseStatisticsVo.setOutNum(outVo.getQuantity());
            }
        }

        return statisticsVoList;
    }
}
